package com.erju.service.impl;

import com.alibaba.excel.EasyExcel;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.erju.dao.UserMapper;
import com.erju.excel.DataListener;
import com.erju.pojo.User;
import com.erju.service.UserService;
import com.erju.utils.BaiduAIUtils;
import com.erju.utils.JasyptUtil;
import com.erju.utils.RedisUtil;
import com.erju.utils.Result;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @Description: 用户信息
 * @author: 86132
 * @date: 2022.03.08
 */
@Service

public class UserServiceImpl implements UserService {

    Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

    @Value("${qiniu.url}")
    private String qiniuUrl;

    @Value("${qiniu.accessKey}")
    private String accessKey;

    @Value("${qiniu.accessSecretKey}")
    private String secretKey;

    @Value("${qiniu.bucket}")
    private String bucket;

    @Autowired
    UserMapper userMapper;

    @Autowired
    RedisUtil redisUtil;

    /**
     * 插入用户
     */
    @Override
    public Result<?> insertUser(User user) {
        user.setPassword(JasyptUtil.setPass(user.getPassword()));
        Boolean result = userMapper.insertUser(user);
        if (result) {
            return Result.success();
        } else {
            return Result.error("插入失败");
        }
    }

    /**
     * 查找所有用户
     *
     * @return
     */
    @Override
    public Result<?> findAllUser() {
        List<User> allUser = userMapper.getAllUser();
        return Result.success("查询成功", allUser);
    }

    /**
     * 根据用户名查权限
     *
     * @param userName
     * @return
     */
    @Override
    public User selectPermissionsByUserName(String userName) {
        return userMapper.selectPermissionsByUserName(userName);
    }

    @Override
    public String uploadPicture(MultipartFile file, String username) throws IOException {
        logger.info("uploadPicture方法-------------");
        Configuration configuration = new Configuration(Region.huabei());
        UploadManager uploadManager = new UploadManager(configuration);
        //生成随机文件名
        String key = getRandomCharacterAndNumber(10) + ".png";
        Auth auth = Auth.create(accessKey, secretKey);
        String uptoken = auth.uploadToken(bucket);
        String responseUrl = "http://";
        try {
            byte[] localFile = file.getBytes();
            Response response = uploadManager.put(localFile, key, uptoken);
            DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
            responseUrl = responseUrl + qiniuUrl + "/" + putRet.key;
            logger.info("最后的responseUrl---" + responseUrl);
            logger.info("uploadPicture方法-------------完了");
            userMapper.updateHeadPicture(responseUrl, username);
        } catch (QiniuException e) {
            Response r = e.response;
        }
        return responseUrl;
    }

    public static String getRandomCharacterAndNumber(int length) {
        String val = "";
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            // 输出字母还是数字
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            // 字符串
            if ("char".equalsIgnoreCase(charOrNum)) {

                // 取得大写字母还是小写字母
                int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char) (choice + random.nextInt(26));
                // int choice = 97; // 指定字符串为小写字母
                val += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) // 数字
            {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

    /**
     * excel 上传
     *
     * @param file
     * @return
     * @throws IOException
     */
    @Override
    public Result upLoad(MultipartFile file) throws IOException {
        try {
            EasyExcel.read(file.getInputStream(), User.class, new DataListener(userMapper))
                    .sheet()
                    .doRead();
            return Result.success("导入成功");
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error(e.getMessage());
        }
    }

    @Override
    public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //数据
            List<User> list = userMapper.selectAllStudent();
            // 这里需要设置不关闭流 数据在response.OutPutStream里面  前端需要res.data
            EasyExcel.write(response.getOutputStream(), User.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(list);
//            return Result.success("导出成功");
        } catch (Exception e) {
            // 重置response
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> map = new HashMap<String, String>();
            map.put("status", "failure");
            map.put("message", "下载文件失败" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(map));
//            return Result.error(e.getMessage());
        }

    }

    /**
     * 获取用户分页信息
     *
     * @return Result
     */
    @Override
    @Transactional
    public Result selectAllPage(HashMap<String, String> map) {
        logger.info("selectAllPage(HashMap<String, String> map)开始-----------------");
        //分页条件
        String pageNum = map.get("pageNum");
        String pageSize = map.get("pageSize");
        //模糊查询条件
        User user = new User();
        String phone_number = map.get("phone_number");
        String account = map.get("account");
        String user_type = map.get("user_type");
        user.setUsername(account == null ? "" : account);
        user.setPhone_number(phone_number == null ? "" : phone_number);
        user.setUser_type(Integer.parseInt(user_type));
        // pageNum:表示第几页  pageSize:表示一页展示的数据
        PageHelper.startPage(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        List<User> users = null;
        try {
            //查询所有学生
            users = userMapper.selectUser(user);
            // 将查询到的数据封装到PageInfo对象
            PageInfo<User> UserPageInfo = new PageInfo(users, Integer.parseInt(pageSize));
            logger.info("selectAllPage(HashMap<String, String> map)结束-----------------");
            // 分割数据成功
            return Result.success("查询成功", UserPageInfo);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            // 将查询到的数据封装到PageInfo对象
            PageInfo<User> UserPageInfo = new PageInfo(null, Integer.parseInt(pageSize));
            // 分割数据成功
            return Result.error(e.getMessage());
        }
    }

    /**
     * 查询个人信息
     *
     * @param account
     * @return
     */
    @Override
    public Result selectPersonalDetails(String account) {
        User user = userMapper.selectPersonalDetails(account);
        return Result.success("查询成功", user);
    }

    @Override
    public Result updatePassword(HashMap<String, String> map) {
        String username = map.get("account");
        User user = userMapper.selectByUserName(username);
        String oldPassword = map.get("oldpassword");
        if (JasyptUtil.getPass(user.getPassword()).equals(oldPassword)) {
            //旧密码正确 ，接下来判断两次新密码是否一致
            if (!map.get("newpassword").equals(map.get("newpasswordAgain"))) {
                return Result.error("两次输入的密码不一致，请重新输入");
            }
            //全部正确 允许更新密码
            String finalPassword = JasyptUtil.setPass(map.get("newpassword"));
            user.setPassword(finalPassword);
            user.setUse_flag(0);
            userMapper.updateUser(user);
            return Result.success("修改成功");

        }
        return Result.error("旧密码不正确，请重新输入");
    }

    /**
     * 修改个人信息
     *
     * @param user
     * @return
     */
    @Override
    public Result updatePersonalDetails(User user) {
        int result = userMapper.updatePersonalDetails(user);
        if (result == 1) {
            return Result.success("修改成功");
        }
        return Result.error("修改失败");
    }

    /**
     * 模糊查询所有用户
     *
     * @param user
     * @return
     */
    @Override
    public Result<?> findUser(User user) {
        user.setUser_type(user.getUser_type() == null ? 2 : user.getUser_type());
        user.setUsername(user.getUsername() == null ? "" : user.getUsername());
        user.setPhone_number(user.getPhone_number() == null ? "" : user.getPhone_number());
        List<User> selectUser = userMapper.selectUser(user);
        return Result.success("查询成功", selectUser);
    }

    /**
     * 更新用户
     *
     * @param user
     * @return
     */
    @Override
    public Result<?> updateUser(User user) {
        Boolean flag = userMapper.updateUser(user);
        return Result.success("查询成功", flag);
    }

    /**
     * 删除用户
     *
     * @param user
     * @return
     */
    @Override
    public Result<?> deleteUser(User user) {
        Boolean flag = userMapper.deleteUser(user);
        return Result.success("查询成功", flag);
    }

    /**
     * id查询用户
     *
     * @param id
     * @return
     */
    @Override
    public Result<?> selectById(Integer id) {
        User user = userMapper.selectById(id);
        return Result.success("查询成功", user);
    }
//获取验证码
    @Override
    public Boolean getCaptcha(String phone_number, String templateCode, Map<String,Object> code) {
        //查询该电话号是否含有用户
        //连接阿里云
        DefaultProfile profile = DefaultProfile.getProfile("cn-qingdao", "LTAI5tHxg7KckYXWqfyChkfW", "5mDjclhnJSMV8mLNUhJiXWRmqEszMt");
        IAcsClient client = new DefaultAcsClient(profile);

        //构建请求
        CommonRequest request = new CommonRequest();
        request.setMethod(MethodType.POST);
        //不能改
        request.setDomain("dysmsapi.aliyuncs.com");
        request.setVersion("2017-05-25");
        request.setAction("SendSms");
        //手机号码 一般填到配置文件里用@Value取值
        request.putQueryParameter("PhoneNumbers", phone_number);
        //签名
        request.putQueryParameter("SignName", "小坏蛋的窝");
        //模板
        request.putQueryParameter("TemplateCode", templateCode);
        //动态验证码 json字符串
        //JSONObject.toJSONString(map)
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(code));
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            return response.getHttpResponse().isSuccess();
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public Result phonenumberResetPassword(String phone_number,String captcha,String newPassword) {
        if(!captcha.equals(redisUtil.get(phone_number))){
            return Result.fail(503,"验证码错误",null);
        }
        User user = userMapper.selectByPhoneNumber(phone_number);
        user.setPassword(newPassword);
        userMapper.updateUser(user);
        return Result.success("200","更改密码成功",null);
    }
}
